package com.jumi.microservice.payment;

import com.alibaba.fastjson.JSON;
import com.aliyun.openservices.ons.api.Message;
import com.aliyun.openservices.ons.api.SendResult;
import com.aliyun.openservices.ons.api.bean.ProducerBean;
import com.jumi.microservice.common.base.dto.BaseRequest;
import com.jumi.microservice.common.base.dto.BaseResponse;
import com.jumi.microservice.common.base.dto.ResponseResult;
import com.jumi.microservice.constant.PayChannelEnum;
import com.jumi.microservice.context.BalanceContext;
import com.jumi.microservice.dto.*;
import com.jumi.microservice.dto.wallet.api.WalletInOrOutRequest;
import com.jumi.microservice.enumerate.WalletTypeEnum;
import com.jumi.microservice.interfaces.BasePayment;
import com.jumi.microservice.interfaces.PayContext;
import com.jumi.microservice.rocketmq.RocketMqConfig;
import com.jumi.microservice.service.IWalletInOrOutService;
import org.apache.dubbo.config.annotation.DubboReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

/**
 * @author Dirk
 * @Date 2020-08-26 16:25
 */
@Component
public class BalancePayment extends BasePayment {

    private static final Logger log = LoggerFactory.getLogger(BasePayment.class);
    @DubboReference
    private IWalletInOrOutService walletInOrOutService;
    @Resource
    ProducerBean producerBean;
    @Autowired
    RocketMqConfig rocketMqConfig;

    @Override
    public PayContext createContext(BaseRequest request) {
        BalanceContext context = new BalanceContext();
        PaymentRequest paymentRequest = (PaymentRequest) request;
        context.setUid(paymentRequest.getUid());
        context.setPayNo(paymentRequest.getPaymentSn());
        context.setAmount(paymentRequest.getTotalAmount());
        context.setRemark(paymentRequest.getSubject());
        return context;
    }

    @Override
    public void preProcess(PayContext context) {

    }

    @Override
    public BaseResponse coreProcess(PayContext context) {
        BalanceContext ctx = (BalanceContext) context;
        WalletInOrOutRequest request = new WalletInOrOutRequest();
        request.setUserId(ctx.getUid());
        request.setOrderNo(ctx.getPayNo());
        request.setAmount(ctx.getAmount());
        request.setRemark(ctx.getRemark());
        request.setType(WalletTypeEnum.PAY_OUT.getCode());
        log.info("余额支付请求参数:[{}]", JSON.toJSONString(request));
        ResponseResult<Boolean> result = walletInOrOutService.walletOut(request);
        if (result.getData()) {
            MqMessage mqMessage = new MqMessage();
            mqMessage.setPayNo(ctx.getPayNo());
            mqMessage.setThirdPartyPaySn(ctx.getPayNo());
            log.info("余额支付发送消息:[{}]", JSON.toJSONString(mqMessage));
            Message message = new Message(rocketMqConfig.getTopic(), rocketMqConfig.getTag(), "", JSON.toJSONBytes(mqMessage));
            SendResult sendResult = producerBean.send(message);
            log.info("余额支付发送消息成功[{}],[{}]", sendResult.getMessageId(), sendResult.getTopic());
        }
        BalancePayResponse response = new BalancePayResponse();
        response.setResult(result.getData());
        return response;
    }

    @Override
    public void afterProcess() {
    }

    @Override
    public String getPayChannel() {
        return PayChannelEnum.BALANCE_PAY.name();
    }

    @Override
    public PaymentResponse refund(BaseRequest request) {
        RefundRequest refundRequest = (RefundRequest) request;
        WalletInOrOutRequest walletInOrOutRequest = new WalletInOrOutRequest();
        walletInOrOutRequest.setUserId(refundRequest.getUid());
        walletInOrOutRequest.setOrderNo(refundRequest.getPayNo());
        walletInOrOutRequest.setAmount(refundRequest.getAmount());
        walletInOrOutRequest.setRemark(refundRequest.getDesc());
        walletInOrOutRequest.setType(WalletTypeEnum.REFUND_IN.getCode());
        log.info("余额支付退款请求参数:[{}]", JSON.toJSONString(walletInOrOutRequest));
        ResponseResult<Boolean> result = walletInOrOutService.walletIn(walletInOrOutRequest);
        PaymentResponse response = new PaymentResponse();
        response.setResult(result.getData());
        return response;
    }

    @Override
    public BaseResponse completePayment(BaseRequest request) {
        return null;
    }
}